package com.module.ble.widget

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.Point
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.core.graphics.scale
import com.common.app.utls.ColorUtils
import com.module.ble.R
import kotlin.math.acos
import kotlin.math.cos
import kotlin.math.pow
import kotlin.math.sin
import kotlin.math.sqrt


/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：2025/29/9
 *
 * 描述：
 *
 * 修订历史：
 *
 */
class CusColorPickView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
    private var bigCircle = 0 // 外圈半径
    private var rudeRadius = 0 // 可移动小球的半径
    private var centerColor = 0 // 可移动小球的颜色
    private var centerBorderColor = 0 // 可移动小球的边框颜色
    private var bitmapBorderBack: Bitmap? = null // 背景图片
    private var bitmapBack: Bitmap? = null // 背景图片
    private var mPaint: Paint? = null // 背景画笔
    private var mCenterPaint: Paint? = null // 可移动小球画笔
    private var mCenterPaintBorder: Paint? = null // 可移动小球边框
    private val centerPoint by lazy { Point(bigCircle, bigCircle) } // 中心位置
    private var mRockPosition: Point? = null // 小球当前位置
    private var listener: OnColorChangedListener? = null // 小球移动的监听
    private var length = 0 // 小球到中心位置的距离
    var paint4: Paint? = null
    var iconRadius: Float = 0f // 吸管圆的半径

    init {
        // 获取自定义组件的属性
        val types = context.obtainStyledAttributes(attrs, R.styleable.ble_color_picker)
        try {
            bigCircle = types.getDimensionPixelOffset(
                R.styleable.ble_color_picker_circle_radius, 100
            )
            rudeRadius = types.getDimensionPixelOffset(
                R.styleable.ble_color_picker_center_radius, 10
            )
            centerColor = types.getColor(
                R.styleable.ble_color_picker_center_color,
                Color.WHITE
            )

            centerBorderColor = types.getColor(
                R.styleable.ble_color_picker_center_border_color,
                Color.BLACK
            )
        } finally {
            // TypeArray用完需要recycle

            types.recycle()
        }
        // 将背景图片大小设置为属性设置的直径
        bitmapBack = BitmapFactory.decodeResource(
            resources,
            R.drawable.ble_pic_color_icon2
        )

        bitmapBorderBack = BitmapFactory.decodeResource(
            resources,
            R.drawable.ble_color_picker_center_border
        )

        bitmapBorderBack = resizeImageToBitmap(bitmapBorderBack!!, rudeRadius * 2, rudeRadius * 2)

        bitmapBack = bitmapBack!!.scale(bigCircle * 2, bigCircle * 2, false)

        // 中心位置坐标
        // 初始化时设置临时中心点
        centerPoint.set(bigCircle, bigCircle)
        mRockPosition = Point(centerPoint)

        // 初始化背景画笔和可移动小球的画笔
        mPaint = Paint()
        mPaint?.isAntiAlias = true

        mCenterPaint = Paint()
        mCenterPaint?.color = centerColor

        mCenterPaintBorder = Paint()
        mCenterPaintBorder?.style = Paint.Style.STROKE
        mCenterPaintBorder?.strokeWidth = 3f
        mCenterPaintBorder?.color = centerBorderColor


        paint4 = Paint()
        iconRadius = ((bitmapBorderBack?.width?:0) / 2).toFloat()
    }

    fun setOnColorChangedListener(listener: OnColorChangedListener) {
        this.listener = listener
    }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)

        // 根据实际控件尺寸重新缩放背景图片
        val originalBitmap = BitmapFactory.decodeResource(
            resources,
            R.drawable.ble_pic_color_icon2
        )
        bitmapBack = originalBitmap.scale(w, h, false)

        // 计算旧中心点和新中心点的偏移比例
        val oldCenterX = centerPoint.x
        val oldCenterY = centerPoint.y
        val newCenterX = w / 2
        val newCenterY = h / 2

        // 更新中心点位置
        centerPoint.set(newCenterX, newCenterY)

        // 更新 bigCircle 的值
        bigCircle = minOf(w, h) / 2

        // 更新小球位置 - 如果小球不在旧中心点，需要按比例调整位置
        mRockPosition?.let { rockPos ->
            if (oldCenterX != 0 && oldCenterY != 0) {
                // 计算小球相对于旧中心点的偏移
                val offsetX = rockPos.x - oldCenterX
                val offsetY = rockPos.y - oldCenterY

                // 计算缩放比例
                val scaleX = newCenterX.toFloat() / oldCenterX.toFloat()
                val scaleY = newCenterY.toFloat() / oldCenterY.toFloat()

                // 按比例调整小球位置
                val newX = newCenterX + (offsetX * scaleX).toInt()
                val newY = newCenterY + (offsetY * scaleY).toInt()

                rockPos.set(newX, newY)
            } else {
                // 如果是第一次初始化，直接设置到新中心点
                rockPos.set(newCenterX, newCenterY)
            }
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        // 画背景图片
        canvas.drawBitmap(bitmapBack!!, 0f, 0f, mPaint)

         //画中心小球
        canvas.drawBitmap(bitmapBorderBack!!, (mRockPosition?.x?:0)-iconRadius, (mRockPosition?.y?:0)-iconRadius, paint4);
    }

    override fun onTouchEvent(event: MotionEvent): Boolean {
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                length = getLength(
                    event.x, event.y, centerPoint.x.toFloat(),
                    centerPoint.y.toFloat()
                )
                if (length > bigCircle - rudeRadius) {
                    return true
                }
            }

            MotionEvent.ACTION_MOVE -> {
                length = getLength(
                    event.x, event.y, centerPoint.x.toFloat(),
                    centerPoint.y.toFloat()
                )
                if (length <= bigCircle - rudeRadius) {
                    mRockPosition?.set(event.x.toInt(), event.y.toInt())
                } else {
                    mRockPosition = getBorderPoint(
                        centerPoint, Point(
                            event.x.toInt(), event.y.toInt()
                        ), bigCircle
                                - rudeRadius
                    )
                }
                conversionColor(bitmapBack?.getPixel(mRockPosition?.x?:0, mRockPosition?.y?:0)?:0)
                mCenterPaint?.color = bitmapBack?.getPixel(mRockPosition?.x?:0, mRockPosition?.y?:0)?:0
            }

            MotionEvent.ACTION_UP -> {}
            else -> {}
        }
        invalidate() // 更新画布
        return true
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
//        // 视图大小设置为直径
//        setMeasuredDimension(bigCircle * 2, bigCircle * 2)

        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val widthSize = MeasureSpec.getSize(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)

        var width = bigCircle * 2
        var height = bigCircle * 2

        // 根据测量模式决定最终尺寸
        when (widthMode) {
            MeasureSpec.EXACTLY -> width = widthSize
            MeasureSpec.AT_MOST -> width = minOf(widthSize, bigCircle * 2)
            MeasureSpec.UNSPECIFIED -> width = bigCircle * 2
        }

        when (heightMode) {
            MeasureSpec.EXACTLY -> height = heightSize
            MeasureSpec.AT_MOST -> height = minOf(heightSize, bigCircle * 2)
            MeasureSpec.UNSPECIFIED -> height = bigCircle * 2
        }

        // 保持正方形（可选）
        val size = minOf(width, height)
        setMeasuredDimension(size, size)
    }

    // 颜色发生变化的回调接口
    interface OnColorChangedListener {
        fun onColorChange(color: Int,red: Int, green: Int, blue: Int)
    }

    companion object {
        /**
         * @param x1
         * @param y1
         * @param x2
         * @param y2
         * @return
         * @describe 计算两点之间的位置
         */
        fun getLength(x1: Float, y1: Float, x2: Float, y2: Float): Int {
            return sqrt((x1 - x2).toDouble().pow(2.0) + (y1 - y2).toDouble().pow(2.0)).toInt()
        }

        /**
         * @param a
         * @param b
         * @param cutRadius
         * @return
         * @describe 当触摸点超出圆的范围的时候，设置小球边缘位置
         */
        fun getBorderPoint(a: Point, b: Point, cutRadius: Int): Point {
            val radian = getRadian(a, b)
            return Point(
                a.x + (cutRadius * cos(radian.toDouble())).toInt(), a.x
                        + (cutRadius * sin(radian.toDouble())).toInt()
            )
        }

        /**
         * @param a
         * @param b
         * @return
         * @describe 触摸点与中心点之间直线与水平方向的夹角角度
         */
        fun getRadian(a: Point, b: Point): Float {
            val lenA: Float = (b.x - a.x).toFloat()
            val lenB: Float = (b.y - a.y).toFloat()
            val lenC = sqrt((lenA * lenA + lenB * lenB).toDouble()).toFloat()
            var ang = acos((lenA / lenC).toDouble()).toFloat()
            ang = ang * (if (b.y < a.y) -1 else 1)
            return ang
        }
    }


    //使用Bitmap加Matrix来缩放
    fun resizeImageToBitmap(bitmap: Bitmap, w: Int, h: Int): Bitmap? {
        val BitmapOrg = bitmap
        val width = BitmapOrg.width
        val height = BitmapOrg.height
        val newWidth = w
        val newHeight = h

        val scaleWidth = (newWidth.toFloat()) / width
        val scaleHeight = (newHeight.toFloat()) / height

        val matrix = Matrix()
        matrix.postScale(scaleWidth, scaleHeight)
        // if you want to rotate the Bitmap
        // matrix.postRotate(45);
        val resizedBitmap: Bitmap? = Bitmap.createBitmap(
            BitmapOrg, 0, 0, width,
            height, matrix, true
        )
        return resizedBitmap
    }

    /**
     * 色值转换
     *
     * @param color
     */
    fun conversionColor(color: Int) {
       val temp =  ColorUtils.colorIntToRgb(color)
        listener?.onColorChange(color, temp[0], temp[1], temp[2])
    }
}